package br.ufpb.di.ppgi.negocio.servicos;

import br.com.caelum.vraptor.ioc.Component;
import br.ufpb.di.ppgi.negocio.iservicos.IService;
import br.ufpb.di.ppgi.negocio.modelo.usuario.Usuario;
import br.ufpb.di.ppgi.negocio.modelo.usuario.UsuarioRole;
import br.ufpb.di.ppgi.persistencia.QueryLocator;
import br.ufpb.di.ppgi.persistencia.domainstore.DomainStore;
import br.ufpb.di.ppgi.util.security.GeradorDeSenha;

@Component
public class InstallService implements IService {
	private final QueryLocator queries;
	private final DomainStore ds;
	private Usuario admin;
	private String password;
	
	public InstallService(QueryLocator queries, DomainStore ds) {
		this.queries = queries;
		this.ds = ds;
	}
	
	/**
	 * Verifica se há uma instalação 
	 * @return
	 */
	public boolean isInstalled() {
		return queries.forUsuario().countSuperUser() > 0;
	}
	
	/**
	 * Instala o ds com o super admin padrão.
	 * @throws IllegalStateException caso ja esteja instalado.
	 */
	public void install() throws IllegalStateException {
		if (isInstalled())
			throw new IllegalStateException("O aplicativo já se encontra instalado");
		
		Usuario usuario = createAdmin();
		ds.add(usuario);
		this.admin = usuario;
	}

	/**
	 * Retorna o admin que foi gerado na instalação corrente, ao invocar {@link #install()}.
	 * @throws IllegalStateException Caso install não seja previamente invocado.
	 */
	public Usuario getGeneratedUserAdmin() throws IllegalStateException {
		if (admin == null)
			throw new IllegalStateException("O aplicativo não foi instalado ainda.");

		return admin;
	}

	private Usuario createAdmin() {
		GeradorDeSenha gerador = GeradorDeSenha.ALPHA_NUMERICO;
		password = gerador.gerarSenha(10);

		Usuario usuario = new Usuario();
		usuario.setEmail("admin-ppgi@ppgi.di.ufpb.br");
		usuario.setNome("SuperAdmin");
		usuario.setCpf("000.000.000-00");
		usuario.setAtivo(true);
		
		usuario.setRole(UsuarioRole.SU);
		usuario.setSenhaDescriptografada(password);
		
		return usuario;
	}

	public String getGeneratedPassword() {
		if (password == null)
			throw new IllegalStateException("O aplicativo não foi instalado ainda.");
		return password;
	}
}
